﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Markup;
using System.IO;

namespace SilverlightOverview
{
    public partial class XamlViewer
    {
        public static readonly DependencyProperty XamlProperty =
            DependencyProperty.Register("Xaml", typeof(string), typeof(XamlViewer), null);

        public static readonly DependencyProperty ShowGridSplitterProperty =
            DependencyProperty.Register("ShowGridSplitter", typeof(bool), typeof(XamlViewer), new PropertyMetadata(true));

        public static readonly DependencyProperty XamlFilenameProperty =
            DependencyProperty.Register("XamlFilename", typeof (string), typeof (XamlViewer), null);

        public string Xaml
        {
            get { return (string)GetValue(XamlProperty); }
            set
            {
                SetValue(XamlProperty, value);
                if (XamlTextBox != null)
                {
                    XamlTextBox.Text = value;

                    // this should only happen if the TextChanged event hasn't been handled, ie during Initialize
                    if (XamlContentControl != null && XamlContentControl.Content == null)
                        LoadXaml();
                }
            }
        }

        public bool ShowGridSplitter
        {
            get { return (bool) GetValue(ShowGridSplitterProperty); }
            set
            {
                SetValue(ShowGridSplitterProperty, value);
                if (splitter != null)
                    splitter.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
                if (XamlTextBox != null)
                    XamlTextBox.Margin = new Thickness(0, value ? 8 : 0, 0, 0);
            }
        }

        public string XamlFilename
        {
            get { return (string) GetValue(XamlFilenameProperty); }
            set
            {
                SetValue(XamlFilenameProperty, value);
                Xaml = LoadXamlFileContents(value);
            }
        }

        public XamlViewer()
        {
            InitializeComponent();
        }

        public XamlViewer(string xamlFilename) : this()
        {
            Xaml = LoadXamlFileContents(xamlFilename);
        }

        private string LoadXamlFileContents(string filename)
        {
            var result = string.Empty;
            try
            {
                using (var s = GetType().Assembly.GetManifestResourceStream(filename))
                {
                    if (s == null)
                        throw new ArgumentException("Invalid XAML Filename - " + filename);

                    using (var sr = new StreamReader(s))
                    {
                        result = sr.ReadToEnd();
                    }
                }
            }
            catch (Exception ex)
            {
                DisplayException(ex);
            }
            return result;
        }

        private void LoadXaml()
        {
            try
            {
                var element = XamlReader.Load(XamlTextBox.Text) as FrameworkElement;
                XamlContentControl.Content = element;
            }
            catch (Exception ex)
            {
                DisplayException(ex);
            }
        }

        private void DisplayException(Exception ex)
        {
            var exElem = new Grid();
            exElem.Children.Add(new TextBlock
                {
                    Text = ex.ToString(),
                    Foreground = new SolidColorBrush(Colors.Red),
                    FontSize = 14,
                });
            XamlContentControl.Content = exElem;
        }

        private void XamlTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            Xaml = XamlTextBox.Text;
            LoadXaml();
        }
    }
}
